﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SDWXServer
{
    public static class RedisManager
    {
        static ServiceStack.Redis.RedisManagerPool redisManager;
        static RedisManager()
        {
            Initialize();
        }
        public static bool InitializeSuccessful { get; private set; }
        public static void Initialize()
        {
            try
            {
                _Host = System.Configuration.ConfigurationManager.AppSettings.Get("RedisHost");

                Dispose();

                redisManager = new ServiceStack.Redis.RedisManagerPool(_Host);
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                }

                InitializeSuccessful = true;
            }
            catch (ServiceStack.Redis.RedisException re)
            {
                InitializeSuccessful = false;
            }
            catch (Exception e)
            {
                InitializeSuccessful = false;
            }
        }

        private static string _Host;
        public static void Dispose()
        {
            if (InitializeSuccessful == false) return;
            try
            {
                if (redisManager != null) redisManager.Dispose();
            }
            catch { }

            InitializeSuccessful = false;
        }

        private static bool IsNeedSave { get; set; }
        public static void Save()
        {
            //if (IsNeedSave == false) return;
            if (InitializeSuccessful == false) return;

            try
            {
                if (redisManager != null)
                {
                    using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                    {
                        redisClient.Save();
                    }
                }
                IsNeedSave = false;
            }
            catch (Exception e)
            {
                KD.Logger.Error("RedisManager-Save", e);
            }
        }

        public static List<T> ClearObjects<T>()
        {
            var list = new List<T>();
            if (InitializeSuccessful == false) return list;

            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.DeleteAll();
                }
                IsNeedSave = true;
            }
            catch { }

            return list;
        }
        public static bool ClearObject<T>(object id)
        {
            var bResult = false;
            if (InitializeSuccessful == false) return bResult;

            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.DeleteById(id);
                }
                bResult = true;
                IsNeedSave = true;
            }
            catch
            {
                bResult = false;
            }

            return bResult;
        }

        public static List<T> GetObjects<T>()
        {
            var list = new List<T>();
            if (InitializeSuccessful == false) return list;

            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    var objs = redisTypeClient.GetAll();
                    if (objs != null) list.AddRange(objs);
                }
            }
            catch (Exception e)
            {
                KD.Logger.Error("RedisManager-GetObjects", e);
            }

            return list;
        }
        public static T GetValue<T>(string key)
        {
            var obj = default(T);
            if (InitializeSuccessful == false) return obj;

            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    obj = redisTypeClient.GetValue(key);
                }
            }
            catch (Exception e)
            {
                KD.Logger.Error("RedisManager-GetValue", e);
            }

            return obj;
        }
        public static bool SetValue<T>(string key, T item)
        {
            if (InitializeSuccessful == false) return false;

            var result = true;
            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.SetValue(key, item);
                }
                IsNeedSave = true;
            }
            catch (Exception e)
            {
                result = false;
                KD.Logger.Error("RedisManager-SetValue", e);
            }

            return result;
        }
        public static bool SetValue<T>(string key, T item, TimeSpan expireIn)
        {
            if (InitializeSuccessful == false) return false;

            var result = true;
            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.SetValue(key, item, expireIn);
                }
                IsNeedSave = true;
            }
            catch (Exception e)
            {
                result = false;
                KD.Logger.Error("RedisManager-SetValue", e);
            }

            return result;
        }
        public static bool SetObject<T>( T item)
        {
            if (InitializeSuccessful == false) return false;

            var result = true;
            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.Store(item);
                }
                IsNeedSave = true;
            }
            catch (Exception e)
            {
                result = false;
                KD.Logger.Error("RedisManager-SetObject", e);
            }

            return result;
        }
        public static bool SetObject<T>(T item, TimeSpan expireIn)
        {
            if (InitializeSuccessful == false) return false;

            var result = true;
            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.Store(item, expireIn);
                }
                IsNeedSave = true;
            }
            catch (Exception e)
            {
                result = false;
                KD.Logger.Error("RedisManager-SetObject", e);
            }

            return result;
        }
        public static T GetObject<T>(object id)
        {
            var obj = default(T);
            if (InitializeSuccessful == false) return obj;

            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    obj = redisTypeClient.GetById(id);
                }
            }
            catch (Exception e)
            {
                KD.Logger.Error("RedisManager-GetObject", e);
            }

            return obj;
        }
        public static bool SetObjects<T>(List<T> items)
        {
            if (InitializeSuccessful == false) return false;

            var result = true;
            try
            {
                using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
                {
                    var redisTypeClient = redisClient.As<T>();
                    redisTypeClient.StoreAll(items);
                }
                IsNeedSave = true;
            }
            catch (Exception e)
            {
                result = false;
                KD.Logger.Error("RedisManager-SetObject", e);
            }

            return result;
        }
        public static Int64 GetNextSequence<T>()
        {
            if (InitializeSuccessful == false) return 0L;

            var id = 0L;
            using (ServiceStack.Redis.IRedisClient redisClient = redisManager.GetClient())
            {
                var redisTypeClient = redisClient.As<T>();
                id = redisTypeClient.GetNextSequence();
            }

            return id;
        }
    }
}
